/*
*	AUTHOR：K老叶
*	NAME：加密器
*	LICENSE：Apache License 2.0
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<windows.h>
#include"encryptor.h"
//#include"framework.h"
#include"FileOperator.h"
//#pragma comment (lib,"DLLENCRYPTOR.lib")
#pragma warning (disable:4996)
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;

void displayMenu();//打印菜单
uchar *encryption(uchar *psk, uchar *c); //加密
uchar *decryption(uchar *psk, uchar *ciphertext);//解密

int main()
{
	uchar choose;
	uchar *file_string,*message,*psk,*ciphertext,*ciphertext2,*msg,*file_name,*cache_string;
	uint i = 0;
	long int l = 0;
	FILE *file ,*cip_file;
	BOOL print_key = TRUE;

	do
	{
		volatile file_string = (uchar*)calloc(0xffff, sizeof(uchar));
		volatile message = (uchar*)calloc(51200, sizeof(uchar));
		volatile psk = (uchar*)calloc(21, sizeof(uchar));
		volatile ciphertext = (uchar*)calloc(0x51200, sizeof(uchar));
		volatile ciphertext2 = (uchar*)calloc(0x51200, sizeof(uchar));
		volatile msg = (uchar*)calloc(5120, sizeof(uchar));
		volatile file_name = (uchar*)calloc(5120, sizeof(uchar));
		volatile cache_string = (uchar*)calloc(0x1ffff, sizeof(uchar));
		displayMenu(print_key);
		scanf("%d", &choose);
		getchar();
		switch (choose)
		{
			case 1:
				puts("输入密码（20位内）：");
				gets(&psk);
				puts("输入明文信息：");
				gets(&message);
				ciphertext = encryption(&psk, &message);
				printf("密文为：\n%s\n", ciphertext);
				system("pause");
				break;
			case 2:
				puts("输入密码（20位内）：");
				gets(&psk);
				puts("请输入密文：");
				gets(&msg);
				ciphertext2 = decryption(&psk, &msg);
				printf("明文：\n%s\n", ciphertext2);
				system("pause");
				break;
			case 3:
				puts("请输入需要加密的文件名（仅限文本文件）：");
				gets(&file_name);
				puts("请输入密码（20位内）：");
				gets(&psk);
				file = fopen(&file_name,"rb");
				if(file == NULL)
				{
					perror("文件错误:");
				}
				strcat(&file_name,".cip");
				fopen(&file_name, "w");
				cip_file = fopen(&file_name, "ab");
				fseek(file,0,SEEK_END);
				l = ftell(file);
				//printf("%ld\n", l);
				fseek(file, 0,SEEK_SET);
				//file_string = (uchar*)realloc
				//(file_string, 0xffff);
				while (l > 0)
				{
					fread(file_string, sizeof(uchar), 0x7ffc, file);
					cache_string = encryption(&psk, file_string);
					fputs(cache_string, cip_file);
					//fprintf(cip_file,"%s",cache_string);
					if (print_key)
					{
						printf("%s", cache_string);
						//printf("-%ld\n", strlen(file_string));
						//printf("+%ld\n",strlen(cache_string));
						//printf("l:%ld\n", l);
						l -= strlen(file_string);
						file_string = (uchar*)calloc(sizeof(uchar), 0xffff);
						cache_string = (uchar*)calloc(0x20000, sizeof(uchar));
					}
				}
				puts("\n\n\n加密完成！\n\n");
				fclose(cip_file);
				fclose(file);
				system("pause");
				break;
			case 4:
				puts("请输入需要解密的文件名（仅限.cip文件）：");
				gets(&file_name);
				puts("请输入密码（20位内）：");
				gets(&psk);
				int psk_len = strlen(&psk);
				cip_file = fopen(&file_name,"rb");
				strcat(&file_name, ".txt");
				fopen(&file_name, "w");
				file = fopen(&file_name, "ab");
				fseek(cip_file, 0, SEEK_END);
				l = ftell(cip_file);
				//printf("%ld\n", l);
				fseek(cip_file, 0, 0);

				//file_string = (uchar*)calloc(0xffff, sizeof(uchar));
				while(l>0)
				{
					fread(file_string, sizeof(uchar), 0xffff / psk_len+1, cip_file);
					cache_string = decryption(&psk, file_string);
					//fprintf(file, "%s", cache_string);
					fputs(cache_string, file);
					if(print_key)printf("%s", cache_string);
					l -= strlen(file_string);
					//printf("%ld\n", l);
					file_string = (uchar*)calloc(sizeof(uchar), 0xffff);
					cache_string = (uchar*)calloc(0x1ffff, sizeof(uchar));
				}
				puts("\n\n\n解密完成！\n\n");
				fclose(file);
				fclose(cip_file);
				system("pause");
				break;
			case 5: print_key = print_key ? 0:1 ; break;
			case 6:exit(0); break;
			default:printf("输入错误\n"); break;
		}
		system("cls");
	} while (1);

	return 0;
}


void displayMenu(BOOL key)
{
	printf("+---------------------+\n");
	printf("+---1.明文加密--------+\n");
	printf("+---2.密文解密--------+\n");
	printf("+---3.文件加密--------+\n");
	printf("+---4.文件解密--------+\n");
	key ? printf("+---5.显示文件内容-开-+\n") : printf("+---5.显示文件内容-关-+\n");
	printf("+---6.退出------------+\n");
	printf("+---------------------+\n");
	printf("输入序号选择操作：");
}